

<script setup>
import { reactive, ref } from 'vue'
import { ElMessage } from 'element-plus'
import Vcode from "vue3-puzzle-vcode";
import { Coordinate } from '@element-plus/icons-vue';
import Cookies from 'js-cookie'
import encrypt from '../utils/crypto'
// 表单数据
let loginForm = reactive({
  username: '',
  password: ''
})
const remeberMe = ref(false)
const isShow = ref(false)
// 表单验证规则[2,4](@ref)
const loginRules = reactive({
  username: [
    { required: true, message: '用户名不能为空', trigger: 'blur' },
    { min: 3, max: 12, message: '账号长度在3到12个字符', trigger: 'blur' }
  ],
  password: [
    { required: true, message: '密码不能为空', trigger: 'blur' },
    { min: 6, max: 16, message: '密码长度在6到16个字符', trigger: 'blur' }
  ]
})

// 表单引用
const loginFormRef = ref(null)
// 临时存储登录表单数据
const tempLoginData = ref(null)

// 记住账密
function getCookie() {
  const username = Cookies.get('username')
  const password = Cookies.get('password')
  const remeberMe = Cookies.get('remeberMe')
  loginForm = {
    username: username === undefined ? loginForm.username : username,
    password: password === undefined ? loginForm.password : decrypt(password),
    remeberMe: remeberMe === undefined ? false : Boolean(remeberMe)

  }
}

// 登录处理
const handleLogin = async () => {
  try {
    // 1. 执行Element Plus内置验证
    await loginFormRef.value.validate((isValid, unValidFields) => {
      if (isValid) {
        if (remeberMe.value) {
          Cookies.set('username', loginForm.username, { expires: 30 })
          Cookies.set('password', encrypt(loginForm.password), { expires: 30 })
          Cookies.set('remeberMe', remeberMe.value, { expires: 30 })
        } else {
          Cookies.remove('username')
          Cookies.remove('password')
          Cookies.remove('remeberMe')
        }
      } else {
        // 遍历并抛出表单错误
        Object.values(unValidFields).forEach(errors => {
          errors.forEach((err) =>{
            throw new Error(err.message)
          })
        })
      }


    }) // [1,3](@ref)
    // 后续登录逻辑

    // 2. 自定义XSS验证（整合到验证规则更佳）
    const xssPattern = /[<>"'{}~?]/g
    const checkXSS = (value) => !xssPattern.test(value)

    // 3. 逐字段验证（替代直接throw）
    if (!checkXSS(loginForm.username)) {

      throw new Error('用户名或密码由数字字母组成!')

    }

    if (!checkXSS(loginForm.password)) {

      throw new Error('用户名或密码由数字字母组成!')

    }

    // 4. 验证通过后显示验证码
    tempLoginData.value = { ...loginForm }
    isShow.value = true // [5](@ref)

  } catch (error) {
    // 5. 自动显示字段错误提示（Element Plus原生特性）
    ElMessage({
      message: error,
      type: 'error',
      plain: true,
    });
  }
}

const onClose = () => {
  isShow.value = false;
};

const onSuccess = () => {
  try {
    // 验证通过， 执行登录逻辑

    ElMessage({
      message: '登录成功!',
      type: 'success',
      plain: true,
    });
    onClose(); // 验证成功，需要手动关闭模态框

  }
  catch (err) {
    ElMessage({
      message: 'Oops! 网络有问题欸! 请稍后再试或联系管理员!',
      type: 'error',
      plain: true,
    });
  }
};

function handleValidateFailed() {
  ElMessage({
    message: 'Oops! 验证码错误! 请重试',
    type: 'error',
    plain: true,
  });
}
// 重置表单
const resetForm = () => {
  loginFormRef.value.resetFields()
}
</script>



<template>
  <div class="login-container">
    <el-card v-model="loginForm" class="login-box" label-width="auto" status-icon>
      <h2 class="title">用户登录</h2>
      <el-form :model="loginForm" :rules="loginRules" ref="loginFormRef" @keyup.enter="handleLogin">
        <!-- 用户名输入 -->
        <el-form-item prop="username">
          <el-input v-model="loginForm.username" placeholder="请输入用户名" prefix-icon="User" clearable
            class="public-input" />
        </el-form-item>

        <!-- 密码输入 -->
        <el-form-item prop="password">
          <el-input v-model="loginForm.password" type="password" placeholder="请输入密码" prefix-icon="Lock" show-password
            clearable class="public-input" />
        </el-form-item>
        <el-form-item>
          <Vcode :show="isShow"  @success="onSuccess" @close="onClose" @fail="handleValidateFailed()" />
        </el-form-item>

        <el-form-item label="记住密码?">
          <el-switch v-model="remeberMe" />
        </el-form-item>
        <!-- 操作按钮 -->
        <el-form-item>
          <div class="control">
            <el-button type="primary" @click="handleLogin()">登录</el-button>
            <el-button @click="resetForm()">重置</el-button>
          </div>

        </el-form-item>
      </el-form>
    </el-card>
  </div>
</template>

<style scoped>
.login-container {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  background: #f0f2f5;
}

.login-box {
  width: 400px;
  padding: 30px;
  border-radius: 8px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
}

.title {
  text-align: center;
  font-size: 24px;
  margin-bottom: 30px;
  font-weight: 700;
}

.public-input {
  height: 48px;
  font-size: 18px;
}

.control {
  display: flex;
  justify-content: space-around;
  width: 100%;
  height: auto;

}

.el-button {
  width: 48%;
}
.validator {
  /* text-align: start; */
  /* border: .7px solid #ccc;

  border-left: 8px solid rgb(64, 158, 255);
  width: 100%;
  height: 40px;
  line-height: 40px; */
  /* padding-left: 20px; */
}
</style>